#include <iostream>
#include <cstdio>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>

int main()
{
    // 1.创建套接字
    // 参数1.协议族,AF_INET: IPv4; 参数2. 通信语意:表示面向连接的TCP套接字; 参数3.具体协议:TCP协议
    int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockfd < 0)
    {
        perror("socket error");
        return -1;
    }
    // 2.绑定地址信息
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8085);                 // htons() :从 主机字节序 转换为 网络字节序
    addr.sin_addr.s_addr = inet_addr("0.0.0.0"); // inet_addr() :将点分十进制 IP 地址（如 "0.0.0.0"）转换为 32 位网络字节序整数。
    socklen_t len = sizeof(struct sockaddr_in);
    int ret = bind(sockfd, (struct sockaddr *)&addr, len);
    if (ret < 0)
    {
        perror("bind error");
        return -1;
    }
    // 3.开始监听
    ret = listen(sockfd, 5); // 参数2.等待连接队列的最大长度//同一时间的并发连接数
    if (ret < 0)
    {
        perror("bind error");
        return -1;
    }


    // 客户端向服务端发起连接
    // 参数1. 客户端套接字文件描述符 ;参数2. :指向 服务器 地址结构体的指针  ;3. :地址结构体的长度
    //  int connect(int sockfd, struct sockaddr* addr, socklen_t len);//和bind()函数类似
    //Client:
    //1.int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    //2.int ret = connect(socked, (socketadd*)addr, len);//返回是否成功


    while (1)
    {
        // 获取新连接
        // 参数2. :用于存储 客户端 地址信息(这里设为NULL表示不关心) 参数3. :地址结构体长度(这里设为0 = NULL)
        //newfd,客户端和服务端建立的新描述符,通过它来进行通信
        int newfd = accept(sockfd, NULL, NULL);
        if (newfd < 0)
        {
            perror("accpet error");
            return -1;
        }
        // 接受数据
        char buf[1024] = {0};
        int ret = recv(newfd, buf, sizeof(buf), 0); // 0表示阻塞
        if (ret < 0)
        {
            perror("recv error");
            close(newfd);
            continue;
        }
        else if (ret == 0)
        {
            // 没有数据
            perror("peer shutdown");
            close(newfd);
            continue;
        }

        // 组织发送的信息(这里是有指定格式的)
        std::string body = "<html><body><h1>Hello World</h1></body></html>";
        std::string rsp = "HTTP/1.1 200 OK\r\n";
        rsp += "Content-length: " + std::to_string(body.size()) + "\r\n";
        rsp += "Content-Type: text/html\r\n";
        rsp += body;

        // 发送数据
        ret = send(newfd, rsp.c_str(), rsp.size(), 0);
        if (ret < 0)
        {
            perror("error send");
            close(newfd);
            continue;
        }
        close(newfd);
    }
    // 关闭连接
    close(sockfd);
    return 0;
}
